package ai.people.netmon.warning.service;

import ai.people.core.common.properties.elastic.ElasticIndex;
import ai.people.core.common.util.ApplicationContextUtil;
import ai.people.core.grpc.lib.es.SearchAccount;
import ai.people.core.grpc.lib.es.SearchResponseData;
import ai.people.core.security.support.RequestHolderUtil;
import ai.people.netmon.framework.domain.warning.entity.*;
import ai.people.netmon.framework.domain.warning.po.WarningAccountAnalysisPO;
import ai.people.netmon.framework.domain.warning.request.account.WarningAccountAnalysisParam;
import ai.people.netmon.framework.domain.warning.vo.MessageAccountInfo;
import ai.people.netmon.framework.domain.warning.vo.MessageContentVO;
import ai.people.netmon.framework.model.response.PageResponse;
import ai.people.netmon.utils.StringPool;
import ai.people.netmon.utils.StringUtils;
import ai.people.netmon.utils.localdateUtil.DateTimeFormatterUtil;
import ai.people.netmon.warning.dict.DictGrpcClient;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 言论预警服务
 *
 * @author yuanqinglong
 * @date 2022/7/27 13:54
 */
public interface WarningSpeechTemplateService<P, R> {

    /**
     * 加入
     */
    String JOINED = "1";
    /**
     * 未加入
     */
    String NOT_JOINED = "0";


    /**
     * 消息列表
     *
     * @param param 参数
     * @return {@link PageResponse}<{@link R}>
     */
    default PageResponse<R> listMessages(P param) {
        // 执行查询ES 处理返回结果
        PageResponse<R> pageResponse = this.searchQuery(param);
        // 获取ES结果 处理数据
        Collection<R> responseList = pageResponse.getList();
        // 处理状态标识
        this.judgingStatus(responseList);
        return pageResponse;
    }


    /**
     * 搜索查询
     *
     * @param param 参数
     * @return {@link PageResponse}<{@link R}>
     */
    PageResponse<R> searchQuery(P param);


    /**
     * 判断状态
     *
     * @param responseList 响应列表
     */
    default void judgingStatus(Collection<R> responseList) {
        // 收藏状态
        List<WarningInfoCollect> warningInfoCollects = this.judgingCollectionStatus(responseList);
        Map<String, WarningInfoCollect> infoCollectMap = warningInfoCollects.stream().collect(Collectors.toMap(warningInfoCollect -> warningInfoCollect.getCollectInfoId() + StringPool.DASH + warningInfoCollect.getCollectUserId() + StringPool.DASH + warningInfoCollect.getCollectInfoPlatform(), Function.identity()));

        // 账号加入分析状态
        List<WarningAccountAnalysisPO> warningAccountAnalyses = this.judgingAnalysisStatus(responseList);
        Map<String, WarningAccountAnalysisPO> accountAnalysisPOMap = warningAccountAnalyses.stream().collect(Collectors.toMap(warningAccountAnalysisPO -> warningAccountAnalysisPO.getAccount() + StringPool.DASH + warningAccountAnalysisPO.getAnalysisUserId() + StringPool.DASH + warningAccountAnalysisPO.getPlatform(), Function.identity()));

        // 加入素材库状态
        List<WarningInfoMaterial> warningInfoMaterials = this.judgingMaterialStatus(responseList);
        Map<String, WarningInfoMaterial> infoMaterialMap = warningInfoMaterials.stream().collect(Collectors.toMap(warningInfoMaterial -> warningInfoMaterial.getMaterialInfoId() + StringPool.DASH + warningInfoMaterial.getMaterialUserId() + StringPool.DASH + warningInfoMaterial.getMaterialInfoPlatform(), Function.identity()));

        DictGrpcClient dictService = ApplicationContextUtil.getBean(DictGrpcClient.class);
        Map<String, String> platformNameMap = dictService.getDictMap("warning_message_source");
        for (R r : responseList) {
            MessageContentVO messageContentVO = (MessageContentVO) r;
            boolean isCollected = infoCollectMap.containsKey(messageContentVO.getId() + StringPool.DASH + RequestHolderUtil.getUserId() + StringPool.DASH + messageContentVO.getPlatform());
            messageContentVO.setCollectStatus(isCollected ? JOINED : NOT_JOINED);
            String account = Optional.ofNullable(messageContentVO.getAccountInfo()).map(MessageAccountInfo::getAccountName).orElse(null);

            boolean isAnalysis = StringUtils.isNotEmpty(account) && accountAnalysisPOMap.containsKey(account + StringPool.DASH + RequestHolderUtil.getUserId() + StringPool.DASH + messageContentVO.getPlatform());
            messageContentVO.setJoinAnalysisStatus(isAnalysis ? JOINED : NOT_JOINED);

            boolean isMaterial = infoMaterialMap.containsKey(messageContentVO.getId() + StringPool.DASH + RequestHolderUtil.getUserId() + StringPool.DASH + messageContentVO.getPlatform());
            messageContentVO.setJoinMaterialStatus(isMaterial ? JOINED : NOT_JOINED);

            messageContentVO.setPlatform(platformNameMap.getOrDefault(messageContentVO.getPlatformCode(), messageContentVO.getPlatformCode()));
        }
    }


    /**
     * 判断收藏状态
     *
     * @param responseList 响应列表
     */
    default List<WarningInfoCollect> judgingCollectionStatus(Collection<R> responseList) {
        List<WarningInfoCollect> checkParamList = responseList.stream().map(r -> {
            MessageContentVO vo = (MessageContentVO) r;
            return WarningInfoCollect.builder().collectUserId(RequestHolderUtil.getUserId()).collectInfoId(vo.getId()).collectInfoPlatform(vo.getPlatform()).build();
        }).collect(Collectors.toList());
        WarningInfoCollectService infoCollectService = ApplicationContextUtil.getBean(WarningInfoCollectService.class, "warningInfoCollectServiceImpl");
        return infoCollectService.batchQueryByParamList(checkParamList);
    }


    /**
     * 判断分析状态
     *
     * @param responseList 响应列表
     */
    default List<WarningAccountAnalysisPO> judgingAnalysisStatus(Collection<R> responseList) {
        List<WarningAccountAnalysisParam> checkParamList = responseList.stream().map(r -> {
            MessageContentVO vo = (MessageContentVO) r;
            return WarningAccountAnalysisParam.builder().analysisUserId(RequestHolderUtil.getUserId()).analysisAccount(vo.getPublisher()).platform(vo.getPlatform()).build();
        }).collect(Collectors.toList());
        WarningAccountAnalysisService warningAccountAnalysisService = ApplicationContextUtil.getBean(WarningAccountAnalysisService.class, "warningAccountCollectServiceImpl");
        return warningAccountAnalysisService.batchQueryAnalysisAccount(checkParamList);
    }


    /**
     * 判断加入素材状态
     *
     * @param responseList 响应列表
     * @return {@link List}<{@link WarningInfoMaterial}>
     */
    default List<WarningInfoMaterial> judgingMaterialStatus(Collection<R> responseList) {
        List<WarningInfoMaterial> checkParamList = responseList.stream().map(r -> {
            MessageContentVO vo = (MessageContentVO) r;
            return WarningInfoMaterial.builder().materialUserId(RequestHolderUtil.getUserId()).materialInfoId(vo.getId()).materialInfoPlatform(vo.getPlatform()).build();
        }).collect(Collectors.toList());
        WarningInfoMaterialService warningInfoMaterialService = ApplicationContextUtil.getBean(WarningInfoMaterialService.class, "warningInfoMaterialServiceImpl");
        return warningInfoMaterialService.batchQueryByParamList(checkParamList);
    }


    /**
     * 对象转换
     *
     * @param searchResponseData 搜索响应数据
     * @param emotionMaps        情感地图
     * @return {@link MessageContentVO}
     */
    default MessageContentVO objectConversion(SearchResponseData searchResponseData, Map<String, String> emotionMaps,Map<String, WarningLabelTree> warningLabelTreeMap) {
        MessageContentVO messageContentVO = MessageContentVO.builder().content(searchResponseData.getContent())
                .label(searchResponseData.getTags())
                .id(searchResponseData.getId())
                .emotion(searchResponseData.getSentiment())
                .title(searchResponseData.getTitle())
                .time(DateTimeFormatterUtil.stringDateFormatterToLocalDateTime(searchResponseData.getPubtime()))
                .publisher(Optional.of(searchResponseData.getAuthor()).map(SearchAccount::getName).orElse(StringPool.EMPTY))
                .emotion(emotionMaps.getOrDefault(searchResponseData.getSentiment(), StringPool.EMPTY))
                .platformCode(searchResponseData.getSource()).build();
        messageContentVO.setPlatformCategory(ElasticIndex.getPlatformClassification(searchResponseData.getSource()));
        if (StringUtils.isNotEmpty(searchResponseData.getTags())){
            String labels = Arrays.stream(searchResponseData.getTags().split(StringPool.COMMA)).map(lb -> {
                WarningLabelTree warningLabelTree = warningLabelTreeMap.getOrDefault(lb, new WarningLabelTree());
                return StringUtils.isNotEmpty(warningLabelTree.getLabelName()) ? warningLabelTree.getLabelName() : lb;
            }).collect(Collectors.joining(StringPool.COMMA));
            messageContentVO.setLabel(labels);
        }
        SearchAccount author = searchResponseData.getAuthor();
        messageContentVO.handleAuthor(author.getId(), author.getName());
        return messageContentVO;
    }




}
